/**
 * WebSocket router
 */
let = express = require("express");
let expressWS = require("express-ws");
const MovieModel = require("../models/movie");
const async = require("async"); //引入async模块
var wsRouter = null;

class WSRouter {
  constructor(server) {
    this.server = server;
    this.app = express();
    this.clients = [];
    this.nms = null;
    expressWS(this.app, this.server);
  }
  /**
   * 接受client端连接
   */
  lintenClientConnect() {
    var me = this;

    this.app.ws("/", function (ws, req) {
      console.log("client connect to server successful!");
      me.clients.push(ws);
      ws.on("message", function (msg) {
        console.log("receive client msg :", msg);
        me.receiveCmd(ws, msg);
      });

      ws.on("close", function (msg) {
        console.log("client is closed");
        for (var index = 0; index < me.clients.length; index++) {
          if (me.clients[index] == this) {
            me.clients.splice(index, 1);
            
          }
        }
        me.sendCmd(ws,'current number of viewers');
        if (!me.clients.length) {
          me.nms && me.nms.stop();
        }
      });
    });
  }
  /**
   * 发送command到client端
   * @param msg
   * @param cb
   */
  sendCmd(ws, msg, cb) {
    var me = this;
    if (msg === 'current number of viewers'){
      ws.send(JSON.stringify({ viewersNumer: me.clients.length }));
    }
    
  }

  /**
   * 接收client的command请求
   * @param cmd
   */
  receiveCmd(ws, cmd) {
    var me = this;
    cmd = JSON.parse(cmd);
    //client start pull stream
    if (
      cmd.startPullStream &&
      cmd.startPullStream.indexOf("start pull stream") === 0
    ) {
      this.startPushStream(cmd.startPullStream.split(" ").pop());
      me.sendCmd(ws,'current number of viewers');
    }
    //心跳
    if (cmd.heartBeat === "server,are you alive?") {
      ws.send(JSON.stringify({ heartBeat: "yes,server is alive" }));
    }

  }

  startPushStream(id) {
    console.log("start push stream", id);
    //从数据库表movie中获取电影id对应的电影地址
    let movieURL = "";
    let movieDirectory = "";
    let movieType = "";
    let tasks = {
      findMovie: (cb) => {
        MovieModel.findByPk(id)
          .then(function (result) {
            if (result) {
              //有结果，保存结果值
              movieURL = result.dataValues.movie_url;
              movieDirectory = result.dataValues.movie_directory;
              movieType = result.dataValues.movie_type;
              cb(null);
            } else {
              console.log("查询电影id失败");
              cb("查询电影id失败");
            }
          })
          .catch(function (err) {
            //错误处理
            console.log(err); //打印错误日志
            cb(err);
          });
      },
      stNodeMediaServer: [
        "findMovie",
        (results, cb) => {
          console.log("movieURL in stNodeMediaServer:", movieURL);
          const NodeMediaServer = require("../utils/NodeMediaServer/node_media_server");
          const config = {
            rtmp: {
              port: 1935,
              chunk_size: 60000,
              gop_cache: true,
              ping: 60,
              ping_timeout: 30,
            },
            http: { port: 8000, allow_origin: "*" },
          };
          this.nms = new NodeMediaServer(config);
          this.nms.run();
          //使用ffmpeg对视频进行推流
          //production <-----> dev
          // let cmdStr = `ffmpeg.exe -re -i D:\\Gitee\\bioscope\\${
          //   movieDirectory ? movieDirectory : "2021-12-23"
          // }\\${
          //   movieURL ? movieURL : "GekkanShoujoNozaki-kun12.mp4"
          // } -vcodec libx264 -acodec copy -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/test`;
          let cmdStr  = `ffmpeg -re -i /usr/yuansong_web/bioscope/${movieDirectory?movieDirectory:'2021-12-23'}/${movieURL?movieURL:'GekkanShoujoNozaki-kun12.mp4'} -vcodec libx264 -acodec copy -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/test`
          
          var exec = require("child_process").exec;
          exec(cmdStr, function (err, stdout, stderr) {
            if (err) {
              console.log("execute ffmpeg error:" + stderr);
              cb(stderr)
            } else {
              cb(null)
            }
          });
        },
      ],
    };

    async.auto(tasks, function (err) {
      if (!!err) {
        console.log(JSON.stringify(err));
      } else {
        console.log(`start push stream ${id} success`);
      }
    });
  }
}

exports.init = function (server) {
  if (wsRouter == null && server != null) {
    wsRouter = new WSRouter(server);
  }
  return wsRouter;
};
